package com.bakery.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bakery.dto.BreadDTO;
import com.bakery.dto.StockChangeDTO;
import com.bakery.entity.Bread;
import com.bakery.entity.Employee;
import com.bakery.entity.StockRecord;
import com.bakery.mapper.BreadMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 面包Service
 *
 * @author bakery
 */
@Service
public class BreadService extends ServiceImpl<BreadMapper, Bread> {
    
    @Autowired
    private EmployeeService employeeService;
    
    @Autowired
    private StockRecordService stockRecordService;
    
    /**
     * 分页查询面包
     */
    public Page<Bread> getBreadPage(Integer page, Integer size, String keyword, String category, Integer status) {
        LambdaQueryWrapper<Bread> wrapper = new LambdaQueryWrapper<>();
        
        if (StrUtil.isNotBlank(keyword)) {
            wrapper.like(Bread::getName, keyword);
        }
        
        if (StrUtil.isNotBlank(category)) {
            wrapper.eq(Bread::getCategory, category);
        }
        
        if (status != null) {
            wrapper.eq(Bread::getStatus, status);
        }
        
        wrapper.orderByDesc(Bread::getCreateTime);
        
        return page(new Page<>(page, size), wrapper);
    }
    
    /**
     * 新增面包
     */
    @Transactional(rollbackFor = Exception.class)
    public void addBread(BreadDTO dto) {
        Bread bread = new Bread();
        bread.setName(dto.getName());
        bread.setCategory(dto.getCategory());
        bread.setPrice(dto.getPrice());
        bread.setSpecification(dto.getSpecification());
        bread.setDescription(dto.getDescription());
        bread.setStock(dto.getStock() != null ? dto.getStock() : 0);
        bread.setStatus(dto.getStatus() != null ? dto.getStatus() : 1);
        
        save(bread);
    }
    
    /**
     * 更新面包
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateBread(BreadDTO dto) {
        Bread bread = getById(dto.getId());
        if (bread == null) {
            throw new RuntimeException("面包不存在");
        }
        
        bread.setName(dto.getName());
        bread.setCategory(dto.getCategory());
        bread.setPrice(dto.getPrice());
        bread.setSpecification(dto.getSpecification());
        bread.setDescription(dto.getDescription());
        
        if (dto.getStatus() != null) {
            bread.setStatus(dto.getStatus());
        }
        
        updateById(bread);
    }
    
    /**
     * 删除（下架）面包
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteBread(Long id) {
        Bread bread = getById(id);
        if (bread == null) {
            throw new RuntimeException("面包不存在");
        }
        
        // 下架而不是删除
        bread.setStatus(0);
        updateById(bread);
    }
    
    /**
     * 库存变动
     */
    @Transactional(rollbackFor = Exception.class)
    public void changeStock(StockChangeDTO dto) {
        Bread bread = getById(dto.getBreadId());
        if (bread == null) {
            throw new RuntimeException("面包不存在");
        }
        
        int beforeStock = bread.getStock();
        int changeQuantity;
        
        // 根据变动类型计算变动数量
        if ("入库".equals(dto.getChangeType())) {
            changeQuantity = dto.getQuantity();
        } else if ("出库".equals(dto.getChangeType())) {
            changeQuantity = -dto.getQuantity();
            if (beforeStock < dto.getQuantity()) {
                throw new RuntimeException("库存不足");
            }
        } else {
            throw new RuntimeException("变动类型错误");
        }
        
        int afterStock = beforeStock + changeQuantity;
        
        // 更新库存
        bread.setStock(afterStock);
        updateById(bread);
        
        // 记录库存变动
        Employee currentEmployee = employeeService.getCurrentEmployee();
        StockRecord record = new StockRecord();
        record.setBreadId(bread.getId());
        record.setChangeType(dto.getChangeType());
        record.setChangeQuantity(changeQuantity);
        record.setBeforeStock(beforeStock);
        record.setAfterStock(afterStock);
        record.setEmployeeId(currentEmployee.getId());
        record.setRemark(dto.getRemark());
        
        stockRecordService.save(record);
    }
    
    /**
     * 批量扣减库存（销售时调用）
     */
    @Transactional(rollbackFor = Exception.class)
    public void deductStock(Long breadId, Integer quantity, Long employeeId) {
        Bread bread = getById(breadId);
        if (bread == null) {
            throw new RuntimeException("面包不存在");
        }
        
        if (bread.getStock() < quantity) {
            throw new RuntimeException(bread.getName() + " 库存不足，当前库存：" + bread.getStock());
        }
        
        int beforeStock = bread.getStock();
        int afterStock = beforeStock - quantity;
        
        // 更新库存
        bread.setStock(afterStock);
        updateById(bread);
        
        // 记录库存变动
        StockRecord record = new StockRecord();
        record.setBreadId(bread.getId());
        record.setChangeType("销售");
        record.setChangeQuantity(-quantity);
        record.setBeforeStock(beforeStock);
        record.setAfterStock(afterStock);
        record.setEmployeeId(employeeId);
        record.setRemark("销售扣减库存");
        
        stockRecordService.save(record);
    }
    
    /**
     * 恢复库存（取消订单时调用）
     */
    @Transactional(rollbackFor = Exception.class)
    public void restoreStock(Long breadId, Integer quantity, Long employeeId) {
        Bread bread = getById(breadId);
        if (bread == null) {
            throw new RuntimeException("面包不存在");
        }
        
        int beforeStock = bread.getStock();
        int afterStock = beforeStock + quantity;
        
        // 更新库存
        bread.setStock(afterStock);
        updateById(bread);
        
        // 记录库存变动
        StockRecord record = new StockRecord();
        record.setBreadId(bread.getId());
        record.setChangeType("入库");
        record.setChangeQuantity(quantity);
        record.setBeforeStock(beforeStock);
        record.setAfterStock(afterStock);
        record.setEmployeeId(employeeId);
        record.setRemark("取消订单恢复库存");
        
        stockRecordService.save(record);
    }
}

